﻿#region File Description

//-----------------------------------------------------------------------------
// Service.svc.cs
//
// Author: ITU Team3 (2012)
//-----------------------------------------------------------------------------

#endregion File Description

#region Using Statements

using System;
using System.Text;
using rentit03_server.Business;
using rentit03_server.Database;

#endregion Using Statements

namespace rentit03_server
{
    /// <summary>
    /// Implementation of the web service interface.
    /// Refer to the IService interface for further documentation.
    /// </summary>
    public class Service : IService
    {
        // Test

        #region Test

        public string HelloWorld()
        {
            return "Hello World!";
        }

        #endregion Test

        #region Login/Logout

        public string Login(string username, string password)
        {
            try
            {
                var sid = SessionHandler.Login(username, password);
                return MagicJSON.GetJsonReturnObject(sid);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string Logout(string sessionId)
        {
            try
            {
                SessionHandler.Logout(sessionId);
                return MagicJSON.GetJsonReturnObject(null, "User succesfully logged out");
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        #endregion Login/Logout

        #region User

        public string CreateUser(string userObj, string sessionId = "")
        {
            try
            {
                var user = MagicJSON.Deserialize<RentitUser>(userObj);
                var uid = UserHandler.CreateUser(user, sessionId);
                return MagicJSON.GetJsonReturnObject("" + uid, "User succesfully created. See value for user id");
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string ReadUserFromSession(string sessionId)
        {
            try
            {
                var user = UserHandler.ReadUser(sessionId);
                return MagicJSON.GetJsonReturnObject(user);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string ReadUser(int userId, string sessionId = "")
        {
            try
            {
                var user = UserHandler.ReadUser(userId, sessionId);
                return MagicJSON.GetJsonReturnObject(user);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string EditUser(int userId, string userObj, string sessionId)
        {
            try
            {
                var user = MagicJSON.Deserialize<RentitUser>(userObj);
                var changed = UserHandler.EditUser(user, userId, sessionId);
                return MagicJSON.GetJsonReturnObject(changed, "User " + userId + " updated in database. Changed values are listed in value");
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string DeleteUser(int userId, string sessionId)
        {
            try
            {
                UserHandler.DeleteUser(userId, sessionId);
                return MagicJSON.GetJsonReturnObject("User with id " + userId + " deleted from database");
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string OverviewUsers(string userSearchParem, string sessionId = "")
        {
            try
            {
                var parem = MagicJSON.Deserialize<UserSearchParameter>(userSearchParem);
                var users = UserHandler.OverviewUsers(parem, sessionId);
                return MagicJSON.GetJsonReturnObject(users);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string OverviewUserCount(string userSearchParems, string sessionId = "")
        {
            try
            {
                var parem = MagicJSON.Deserialize<UserSearchParameter>(userSearchParems);
                var count = UserHandler.OverviewUserCount(parem, sessionId);
                return MagicJSON.GetJsonReturnObject(count);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        #endregion User

        #region Credits

        public string ReadCredits(int userId, string sessionId)
        {
            try
            {
                var a = UserHandler.ReadCredits(userId, sessionId);
                return MagicJSON.GetJsonReturnObject(a);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string EditCredits(int userId, int amount, string sessionId)
        {
            try
            {
                var bc = UserHandler.ReadUser(userId, sessionId).Credits;
                var user = UserHandler.EditCredits(userId, amount, sessionId);
                var ac = UserHandler.ReadUser(userId, sessionId).Credits;
                return MagicJSON.GetJsonReturnObject(user, "Updated creadits from " + bc + " to " + ac);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        #endregion Credits

        #region Media

        public string CreateMedia(string mediaObj, string sessionId)
        {
            try
            {
                var media = MagicJSON.Deserialize<RentitMedia>(mediaObj);

                if (media.Type == null)
                    throw new RentitException(ReturnStatus.MediaValidateType, "Type must not be null");

                if (media.Type.ToLower().Equals("movie"))
                {
                    media = MagicJSON.Deserialize<RentitMovie>(mediaObj);
                }
                else
                {
                    throw new RentitException(ReturnStatus.MediaValidateType, "Unable to recognize type");
                }

                var mid = MediaHandler.CreateMedia(media, sessionId);
                return MagicJSON.GetJsonReturnObject(mid);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string ReadMedia(int mediaId, string sessionId = "")
        {
            try
            {
                var media = MediaHandler.ReadMedia(mediaId, sessionId);
                return MagicJSON.GetJsonReturnObject(media);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string ReadMediaFromVersionId(int versionId, string sessionId = "")
        {
            try
            {
                var media = MediaHandler.ReadMediaFromVersionId(versionId, sessionId);
                return MagicJSON.GetJsonReturnObject(media);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string EditMedia(int mediaId, string mediaObj, string sessionId)
        {
            try
            {
                var media = MagicJSON.Deserialize<RentitMovie>(mediaObj); // Skal laves om til RentitMedia senere. Er midlertidigt RentitMovie for at virke med det smu har
                MediaHandler.EditMedia(media, mediaId, sessionId);
                return MagicJSON.GetJsonReturnObject("Media updated in the database");
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string DeleteMedia(int mediaId, string sessionId)
        {
            try
            {
                MediaHandler.DeleteMedia(mediaId, sessionId);
                return MagicJSON.GetJsonReturnObject("Media removed from database");
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string OverviewMediaCount(string mediaSearchParems, string sessionId = "")
        {
            try
            {
                var parem = MagicJSON.Deserialize<MediaSearchParameter>(mediaSearchParems);
                var count = MediaHandler.OverviewMediaCount(parem, sessionId);
                return MagicJSON.GetJsonReturnObject(count);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string OverviewMedia(string mediaSearchParems, string sessionId = "")
        {
            try
            {
                var parem = MagicJSON.Deserialize<MediaSearchParameter>(mediaSearchParems);
                var media = MediaHandler.OverviewMedia(parem, sessionId);
                return MagicJSON.GetJsonReturnObject(media);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string OverviewVersions(int mediaId, string sessionId = "")
        {
            try
            {
                var versions = MediaHandler.OverviewVersions(mediaId, sessionId);
                return MagicJSON.GetJsonReturnObject(versions);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string OverviewGenres(string sessionId = "")
        {
            try
            {
                var genres = MediaHandler.OverviewGenres(sessionId);
                return MagicJSON.GetJsonReturnObject(genres);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string OverviewLanguages(string sessionId = "")
        {
            try
            {
                var languages = MediaHandler.OverviewLanguages(sessionId);
                return MagicJSON.GetJsonReturnObject(languages);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        #endregion Media

        #region Comments

        public string CreateComment(string commentObj, string sessionId)
        {
            try
            {
                var comment = MagicJSON.Deserialize<RentitComment>(commentObj);
                var id = CommentHandler.CreateComment(comment, sessionId);
                return MagicJSON.GetJsonReturnObject(id);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string ReadComment(int commentId, string sessionId)
        {
            try
            {
                var comment = CommentHandler.ReadComment(commentId, sessionId);
                return MagicJSON.GetJsonReturnObject(comment);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string EditComment(int commentId, string commentObj, string sessionId)
        {
            try
            {
                var comment = MagicJSON.Deserialize<RentitComment>(commentObj);
                CommentHandler.EditComment(commentId, comment, sessionId);
                return MagicJSON.GetJsonReturnObject("Comment updated in the database");
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string DeleteComment(int commentId, string sessionId)
        {
            try
            {
                var mediaId = CommentHandler.DeleteComment(commentId, sessionId);
                return MagicJSON.GetJsonReturnObject(mediaId + "", "Comment removed from database. Media id is stored in value");
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        #endregion Comments

        #region Shopping Cart

        public string GetCart(string sessionId)
        {
            try
            {
                var cart = ShoppingCart.GetCart(sessionId);
                return MagicJSON.GetJsonReturnObject(cart);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string AddToCart(int versionId, string sessionId)
        {
            try
            {
                ShoppingCart.AddToCart(versionId, sessionId);
                return MagicJSON.GetJsonReturnObject();
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string RemoveFromCart(int versionId, string sessionId)
        {
            try
            {
                ShoppingCart.RemoveFromCart(versionId, sessionId);
                return MagicJSON.GetJsonReturnObject();
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string ClearCart(string sessionId)
        {
            try
            {
                ShoppingCart.ClearCart(sessionId);
                return MagicJSON.GetJsonReturnObject();
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string CheckOutCart(string sessionId)
        {
            try
            {
                var receipt = ShoppingCart.CheckOutCart(sessionId);
                return MagicJSON.GetJsonReturnObject(receipt);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string OverviewPurchases(string sessionId)
        {
            try
            {
                var purchases = ShoppingCart.OverviewPurchases(sessionId);
                return MagicJSON.GetJsonReturnObject(purchases);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        #endregion Shopping Cart

        #region top

        public string TopRatedMovies(int page, int count, string sessionId)
        {
            try
            {
                var movies = MediaHandler.TopRatedMovies(page, count, sessionId);
                return MagicJSON.GetJsonReturnObject(movies);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string RandomMovies(int count, string sessionId)
        {
            try
            {
                var movies = MediaHandler.RandomMovies(count, sessionId);
                return MagicJSON.GetJsonReturnObject(movies);
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        #endregion top

        #region Other

        public string GetReturnStatuses()
        {
            var sb = new StringBuilder();

            foreach (ReturnStatus value in Enum.GetValues(typeof(ReturnStatus)))
            {
                var code = (int)value;
                var name = Enum.GetName(typeof(ReturnStatus), value);

                if (code % 100 == 0)
                    sb.AppendFormat("\n" + name + "\n");
                else
                    sb.AppendFormat("{0,3}: {1}\n", code, name);
            }

            return sb.ToString();
        }

        public string GetPermissions()
        {
            var sb = new StringBuilder();

            foreach (PermissionEnum value in Enum.GetValues(typeof(PermissionEnum)))
            {
                var code = (int)value;
                var name = Enum.GetName(typeof(PermissionEnum), value);

                if (code % 100 == 0)
                    sb.AppendFormat("\n" + name + "\n");
                else
                    sb.AppendFormat("{0,3}: {1}\n", code, name);
            }

            return sb.ToString();
        }

        public string CreateRole(string role, string sessionId)
        {
            var rId = SessionHandler.CreateRole(MagicJSON.Deserialize<RentitRole>(role), sessionId);
            return MagicJSON.GetJsonReturnObject("" + rId, "Role succesfully created. See value for role id");
        }

        public string ReadRole(int roleId, string sessionId)
        {
            var role = SessionHandler.ReadRole(roleId, sessionId);
            return MagicJSON.GetJsonReturnObject(role);
        }

        public string CreatePermission(string permission, string sessionId)
        {
            try
            {
                var pId = SessionHandler.CreatePermission(MagicJSON.Deserialize<RentitPermission>(permission), sessionId);
                return MagicJSON.GetJsonReturnObject("" + pId, "Permission succesfully created. See value for permission id");
            }
            catch (RentitException e)
            {
                return e.ToJsonReturnObject();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        public string PopulateDatabase()
        {
            try
            {
                DatabasePopulator.CreatePermissions();
                DatabasePopulator.CreateRoles();
                DatabasePopulator.CreateUsers();
                return "Yes!";
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        #endregion Other
    }
}